package com.gaswell.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gaswell.entity.Qba01;
import com.gaswell.mapper.Qba01Mapper;
import com.gaswell.service.IQba01Service;
import com.gaswell.service.QjService;
import com.gaswell.utils.DateUtils;
import com.gaswell.utils.ObjectUtils;
import com.gaswell.vo.Qba01Vo;
import com.gaswell.vo.Qba01Vo2;
import com.gaswell.vo.QjVo;
import com.gaswell.vo.Result;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.session.ResultHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.sql.Date;
import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.Future;

/**
 * <p>
 * 采气井日数据 服务实现类
 * </p>
 *
 * @author Lei Wang
 * @since 2022-05-24
 */
@Service
@DS("oracle")
public class Qba01ServiceImpl extends ServiceImpl<Qba01Mapper, Qba01> implements IQba01Service {

    @Autowired
    private Qba01Mapper qba01Mapper;
    @Autowired
    private QjService qjService;

    @Autowired
    Qba01Service2Impl qba01Service2;


    @Override
    public Map selectByMutliProperties(String start, String end, String type, String jh, int sort, int current, int size, Integer sfsjh, String token, List<String> ywbhs, List<String> zwbhs) {
        HashMap<String, Object> stringObjectHashMap = new HashMap<>();
        LambdaQueryWrapper<Qba01> qba01MLambdaQueryWrapper = new LambdaQueryWrapper<>();
        List<String> finalZwbhs = zwbhs;
        List<String> finalYwbhs = ywbhs;
        qba01MLambdaQueryWrapper.and(q -> q.in(Qba01::getJh, finalZwbhs).or().in(Qba01::getJh, finalYwbhs));
        if (type.equals("1") && StringUtils.isNotBlank(start)) {
//            单天查询
            qba01MLambdaQueryWrapper.eq(Qba01::getRq, DateUtils.stringTosqldate(start));
        } else if (type.equals("2")) {
//            按时间段查询
            if (StringUtils.isNotBlank(start))
                qba01MLambdaQueryWrapper.ge(Qba01::getRq, DateUtils.stringTosqldate(start));
            if (StringUtils.isNotBlank(end))
                qba01MLambdaQueryWrapper.le(Qba01::getRq, DateUtils.stringTosqldate(end));
        }


        if (sort == 0)
            qba01MLambdaQueryWrapper.orderByDesc(Qba01::getRq);
        else
            qba01MLambdaQueryWrapper.orderByAsc(Qba01::getRq);


        List<Qba01> list = null;
        Long total = Long.valueOf(0);
        Long current_page = Long.valueOf(0);

        if (current != -1 && size != -1) {
            Page<Qba01> page = new Page<>(current, size);
            Page<Qba01> page1 = this.page(page, qba01MLambdaQueryWrapper);
            list = page1.getRecords();
            total = page1.getTotal();
            current_page = page1.getPages();
        } else {
            list = this.list(qba01MLambdaQueryWrapper);
            total = Long.valueOf(list.size());
        }

        stringObjectHashMap.put("list", list);
        stringObjectHashMap.put("total", total);
        stringObjectHashMap.put("current_page", current_page);
        return stringObjectHashMap;
    }

    @Override
    public IPage getByPropertiesDirectSingleThread(Timestamp start, String end, String type, String jh, int sort, int current, int size, Integer sfsjh, String token, List<String> ywbhs, List<String> zwbhs) {
         Page qba01Vo2Page = new Page<>(current, size);
         IPage<Qba01Vo2> byPropertiesDirectSingleThread = qba01Mapper.getByPropertiesDirectSingleThread(qba01Vo2Page, start, end, type, jh, sort, sfsjh, ywbhs, zwbhs);
        return byPropertiesDirectSingleThread;
    }

    @Override
    public List selectDuringTimeMultiThread(List<String> ywbhs, List<String> zwbhs) {
        List<Future<Boolean>> futureList = new ArrayList<>();
        HashMap<String, Integer> stringIntegerHashMap = new HashMap<>();
        LambdaQueryWrapper<Qba01> qba01LambdaQueryWrapper = new LambdaQueryWrapper<>();
        qba01LambdaQueryWrapper.and(q -> q.in(Qba01::getJh, ywbhs).or().in(Qba01::getJh, zwbhs));
        Integer count = baseMapper.selectCount(qba01LambdaQueryWrapper);
        System.out.println(count);

//      设置每页的数量
        int pagesize = 10000;

        int times = count / pagesize;


        for (int i = 0; i < times; i++) {
//          多线程查询并统计
            Future<Boolean> booleanFuture = qba01Service2.pageForMultiThread(qba01LambdaQueryWrapper, i, pagesize, stringIntegerHashMap);
            futureList.add(booleanFuture);
        }
        for (Future<?> future : futureList) {
            while (true) {//CPU高速轮询：每个future都并发轮循，判断完成状态然后获取结果，这一行，是本实现方案的精髓所在。即有10个future在高速轮询，完成一个future的获取结果，就关闭一个轮询
                if (future.isDone() && !future.isCancelled()) { //获取future成功完成状态，如果想要限制每个任务的超时时间，取消本行的状态判断+future.get(1000*1, TimeUnit.MILLISECONDS)+catch超时异常使用即可。
                    break;//当前future获取结果完毕，跳出while
                } else {
                    try {
                        Thread.sleep(1);//每次轮询休息1毫秒（CPU纳秒级），避免CPU高速轮循耗空CPU
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        System.out.println(stringIntegerHashMap);


        return null;
    }

    @Override
    public Result insertOne(Qba01 qba01) {
        qba01Mapper.insert(qba01);
        return Result.success(qba01);
    }

    @Override
    public Result updateOne(Qba01 qba01) {
        qba01Mapper.updateById(qba01);
        return Result.success(qba01);
    }

    @Override
    public Result selectProperties(Qba01 qba01, int sort, int department, String start, String end) {
        Class cls = qba01.getClass();
        Field[] fields = cls.getDeclaredFields();
        QueryWrapper<Qba01> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(start) && StringUtils.isNotBlank(end)) {
            Date down_date = ObjectUtils.dateFormat2Date(start);
            Date up_date = ObjectUtils.dateFormat2Date(end);
            queryWrapper.ge("RQ", down_date)
                    .le("RQ", up_date);
        }


        for (Field field : fields) {
            String fname = field.getName();
            String type = field.getGenericType().toString();

            field.setAccessible(true);
            try {

                if (type.equals("class java.lang.String") && StringUtils.isNotBlank(field.get(qba01).toString())) {

                    if (fname.equals("rq")) {
                        Date down_date = ObjectUtils.dateFormat2Date(field.get(qba01).toString());
                        queryWrapper.eq("RQ", down_date);
//                        queryWrapper.apply("to_char(to_date(rq，'yyyy-MM-dd'),'yyyy-MM-dd') >= {0}", down);
//                        queryWrapper.apply("to_char(to_date(rq，'yyyy-MM-dd'),'yyyy-MM-dd') <= {0}", up);

                    } else {
                        queryWrapper.eq(fname, field.get(qba01).toString());
                    }


                }
                if (type.equals("java.math.BigDecimal") && Double.valueOf(field.get(qba01).toString()) != 0) {
                    queryWrapper.eq(fname, Double.valueOf(field.get(qba01).toString()));
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
//        Page<Qba01> page=new Page<>(current,size);
//        qba01Mapper.selectPage(page, queryWrapper);
//        return new Result(true,200,"success",page.getRecords(),(int)page.getTotal(),(int)page.getPages());
//        queryWrapper.orderByAsc("rq");
        if (department == 2) {
            List<String> lists = qjService.findJhByYm("川渝");
            queryWrapper.in("JH", lists);
        }
        if (department == 3) {
            List<String> lists = qjService.findJhByYm("大庆");
            queryWrapper.in("JH", lists);
        }
        if (sort == 0)
            queryWrapper.orderByAsc("RQ");
        else
            queryWrapper.orderByDesc("RQ");
        List<Qba01> list = qba01Mapper.selectList(queryWrapper);
//        if (list.size() != 0 && list != null)
//            if (sort == 0)
//                Collections.sort(list);
//            else
//                Collections.sort(list, Collections.reverseOrder());
        return Result.success(list);
    }

    @Override
    public Result selectAll(int current, int size, String jh, int sort) {
        Page<Qba01> page = new Page<>(current, size);
        LambdaQueryWrapper<Qba01> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StringUtils.isNotBlank(jh), Qba01::getJh, jh);
        if (sort == 0)
            lambdaQueryWrapper.orderByAsc(Qba01::getRq);
//            lambdaQueryWrapper.last("order by to_char(to_date(rq，'yyyy-MM-dd'),'yyyy-MM-dd') asc");
        else
            lambdaQueryWrapper.orderByDesc(Qba01::getRq);
//            lambdaQueryWrapper.last("order by to_char(to_date(rq，'yyyy-MM-dd'),'yyyy-MM-dd') desc");
        qba01Mapper.selectPage(page, lambdaQueryWrapper);
        return new Result(true, 200, "success", page.getRecords(), (int) page.getTotal(), (int) page.getPages());
    }

    @Override
    public Qba01 selectLastOne() {

        return qba01Mapper.selectLastOne();
    }

    @Override
    public Qba01 setByDate(String s, String jh) {
        LambdaQueryWrapper<Qba01> lqw = new LambdaQueryWrapper<>();
        Date date = ObjectUtils.dateFormat2Date(s);
        lqw.eq(Qba01::getRq, date);
        lqw.eq(Qba01::getJh, jh);
        return qba01Mapper.selectOne(lqw);
    }

    @Override
    public Qba01 setByDateLast(String jh) {
        QueryWrapper<Qba01> queryWrapper = new QueryWrapper();
        queryWrapper.eq("jh", jh);
        queryWrapper.orderByDesc("rq");
        List<Qba01> qba01s = qba01Mapper.selectList(queryWrapper);

        if (qba01s.size() > 0) {
            return qba01s.get(0);
        }
        return null;
    }

    //    @Async
    @Override
    public Qba01 getByDateLast(String ywbh, String zwbh) {
        return baseMapper.getLatest(ywbh, zwbh);
    }



    @Override
    public List<Qba01> GetByDateLast(List<String> zwbhs, List<String> ywbhs) {
        return baseMapper.getLatestForList(ywbhs,zwbhs);
    }


    @Override
    public void streamQuery(String sql, ResultHandler<Qba01> handler) {
        baseMapper.streamQuery(sql, handler);
    }

    @Override
    public Result selectByMutiProperties(Qba01Vo qba01Vo, String date, int sort, int department) {
        int len = qba01Vo.getOptions().size();
        List<String> options = qba01Vo.getOptions();
        String property = qba01Vo.getProperty();
        LambdaQueryWrapper<Qba01> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(date)) {
            String[] dates = date.split(",");
            String down = dates[0];
            String up = dates[1];
            Date down_date = ObjectUtils.dateFormat2Date(down);
            Date up_date = ObjectUtils.dateFormat2Date(up);
            lambdaQueryWrapper.ge(Qba01::getRq, down_date)
                    .le(Qba01::getRq, up_date);
//            lambdaQueryWrapper.apply("to_char(to_date(rq，'yyyy-MM-dd'),'yyyy-MM-dd') >= {0}", down);
//            lambdaQueryWrapper.apply("to_char(to_date(rq，'yyyy-MM-dd'),'yyyy-MM-dd') <= {0}", up);
        }
        if (sort == 0)
            lambdaQueryWrapper.orderByAsc(Qba01::getRq);
//            lambdaQueryWrapper.last("order by to_char(to_date(rq，'yyyy-MM-dd'),'yyyy-MM-dd') asc");
        else
            lambdaQueryWrapper.orderByDesc(Qba01::getRq);
//            lambdaQueryWrapper.last("order by to_char(to_date(rq，'yyyy-MM-dd'),'yyyy-MM-dd') desc");
        if (len == 0) {
            Result.success(qba01Mapper.selectList(lambdaQueryWrapper));
        }
        if (property.equals("jh")) {
            List<QjVo> jhByJhs = qjService.findJhByJhs(options);
            List<String> zwbhs = new LinkedList<>();
            List<String> ywbhs = new LinkedList<>();
            jhByJhs.forEach(jh -> {
                zwbhs.add(jh.getZwbh());
                ywbhs.add(jh.getYwbh());
            });
            if (zwbhs.size() == 0 && ywbhs.size() == 0) {
                lambdaQueryWrapper.in(Qba01::getJh, options);
            } else {
//                lambdaQueryWrapper.in(Qba01::getJh, options);
                lambdaQueryWrapper.and(l -> l.in(Qba01::getJh, ywbhs).or().in(Qba01::getJh, zwbhs));
            }

        } else if (property.equals("qm")) {
            lambdaQueryWrapper.in(Qba01::getQm, options);
        } else if (property.equals("zm")) {
            lambdaQueryWrapper.in(Qba01::getZm, options);
        } else if (property.equals("dm")) {
            lambdaQueryWrapper.in(Qba01::getDm, options);
        } else if (property.equals("zyq")) {
            lambdaQueryWrapper.in(Qba01::getZyq, options);
        } else if (property.equals("qkmc")) {
            lambdaQueryWrapper.in(Qba01::getQcdk, options);
        }
        List<String> zwbhs = new LinkedList<>();
        List<String> ywbhs = new LinkedList<>();
        if (department == 2) {
            List<QjVo> jhs = qjService.findZwbhByYm("川渝");
            jhs.forEach(jh -> {
                zwbhs.add(jh.getZwbh());
                ywbhs.add(jh.getYwbh());
            });
            lambdaQueryWrapper.and(l -> l.in(Qba01::getJh, ywbhs).or().in(Qba01::getJh, zwbhs));
        }
        if (department == 3) {
            List<QjVo> jhs = qjService.findZwbhByYm("大庆");
            jhs.forEach(jh -> {
                zwbhs.add(jh.getZwbh());
                ywbhs.add(jh.getYwbh());
            });
            lambdaQueryWrapper.and(l -> l.in(Qba01::getJh, ywbhs).or().in(Qba01::getJh, zwbhs));
        }

        return Result.success(qba01Mapper.selectList(lambdaQueryWrapper));
    }

    @Override
    public Result pageByMutiProperties(Qba01Vo qba01Vo, String date, int sort, int department, int current, int size) {
        int len = qba01Vo.getOptions().size();
        List<String> options = qba01Vo.getOptions();
        String property = qba01Vo.getProperty();
        LambdaQueryWrapper<Qba01> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(date)) {
            String[] dates = date.split(",");
            String down = dates[0];
            String up = dates[1];
            Date down_date = ObjectUtils.dateFormat2Date(down);
            Date up_date = ObjectUtils.dateFormat2Date(up);
            lambdaQueryWrapper.ge(Qba01::getRq, down_date)
                    .le(Qba01::getRq, up_date);
//            lambdaQueryWrapper.apply("to_char(to_date(rq，'yyyy-MM-dd'),'yyyy-MM-dd') >= {0}", down);
//            lambdaQueryWrapper.apply("to_char(to_date(rq，'yyyy-MM-dd'),'yyyy-MM-dd') <= {0}", up);
        }
        if (sort == 0)
            lambdaQueryWrapper.orderByAsc(Qba01::getRq);
//            lambdaQueryWrapper.last("order by to_char(to_date(rq，'yyyy-MM-dd'),'yyyy-MM-dd') asc");
        else
            lambdaQueryWrapper.orderByDesc(Qba01::getRq);
//            lambdaQueryWrapper.last("order by to_char(to_date(rq，'yyyy-MM-dd'),'yyyy-MM-dd') desc");
        if (len == 0) {
            Result.success(qba01Mapper.selectList(lambdaQueryWrapper));
        }
        if (property.equals("jh")) {
            List<QjVo> jhByJhs = qjService.findJhByJhs(options);
            List<String> zwbhs = new LinkedList<>();
            List<String> ywbhs = new LinkedList<>();
            jhByJhs.forEach(jh -> {
                zwbhs.add(jh.getZwbh());
                ywbhs.add(jh.getYwbh());
            });
            if (zwbhs.size() == 0 && ywbhs.size() == 0) {
                lambdaQueryWrapper.in(Qba01::getJh, options);
            } else {
//                lambdaQueryWrapper.in(Qba01::getJh, options);
                lambdaQueryWrapper.and(l -> l.in(Qba01::getJh, ywbhs).or().in(Qba01::getJh, zwbhs));
            }

        } else if (property.equals("qm")) {
            lambdaQueryWrapper.in(Qba01::getQm, options);
        } else if (property.equals("zm")) {
            lambdaQueryWrapper.in(Qba01::getZm, options);
        } else if (property.equals("dm")) {
            lambdaQueryWrapper.in(Qba01::getDm, options);
        } else if (property.equals("zyq")) {
            lambdaQueryWrapper.in(Qba01::getZyq, options);
        } else if (property.equals("qkmc")) {
            lambdaQueryWrapper.in(Qba01::getQcdk, options);
        }
        List<String> zwbhs = new LinkedList<>();
        List<String> ywbhs = new LinkedList<>();
        if (department == 2) {
            List<QjVo> jhs = qjService.findZwbhByYm("川渝");
            jhs.forEach(jh -> {
                zwbhs.add(jh.getZwbh());
                ywbhs.add(jh.getYwbh());
            });
            lambdaQueryWrapper.and(l -> l.in(Qba01::getJh, ywbhs).or().in(Qba01::getJh, zwbhs));
        }
        if (department == 3) {
            List<QjVo> jhs = qjService.findZwbhByYm("大庆");
            jhs.forEach(jh -> {
                zwbhs.add(jh.getZwbh());
                ywbhs.add(jh.getYwbh());
            });
            lambdaQueryWrapper.and(l -> l.in(Qba01::getJh, ywbhs).or().in(Qba01::getJh, zwbhs));
        }
        Page<Qba01> page = new Page<>(current, size);

        Page<Qba01> qba01Page = qba01Mapper.selectPage(page, lambdaQueryWrapper);
        return new Result(true, 200, "success", qba01Page.getRecords(), (int) qba01Page.getTotal(), (int) qba01Page.getPages());
    }

    @Override
    public Result findQm() {
        QueryWrapper<Qba01> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("distinct qm");
        List<Map<String, Object>> maps = qba01Mapper.selectMaps(queryWrapper);
        return Result.success(maps);
    }

    @Override
    public Result findZm() {
        QueryWrapper<Qba01> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("distinct zm");
        List<Map<String, Object>> maps = qba01Mapper.selectMaps(queryWrapper);
        return Result.success(maps);
    }

    @Override
    public Result findDm() {
        QueryWrapper<Qba01> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("distinct dm");
        List<Map<String, Object>> maps = qba01Mapper.selectMaps(queryWrapper);
        return Result.success(maps);
    }

    @Override
    public Result findZyq() {
        QueryWrapper<Qba01> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("distinct zyq");
        List<Map<String, Object>> maps = qba01Mapper.selectMaps(queryWrapper);
        return Result.success(maps);
    }

    @Override
    public Result findQkmc() {
        QueryWrapper<Qba01> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("distinct qcdk");
        List<Map<String, Object>> maps = qba01Mapper.selectMaps(queryWrapper);
        return Result.success(maps);
    }
}
